package com.tensquare.article.service;

import com.tensquare.article.dao.CommentDao;
import com.tensquare.article.pojo.Comment;
import com.tensquare.exception.TensquareException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import util.IdWorker;

import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
public class CommentService {

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private CommentDao commentDao;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 添加评论
     * @param comment
     */
    public void add(Comment comment) {
        comment.set_id(idWorker.nextId() + "");
        comment.setPublishdate(new Date());
        comment.setThumbup(0);

        // 调用dao保存
        commentDao.save(comment);
    }

    /**
     * 查询所有
     * @return
     */
    public List<Comment> findAll() {
        return commentDao.findAll();
    }

    /**
     * 通过编号查询
     * @param commentId
     * @return
     */
    public Comment findById(String commentId) {
        Optional<Comment> optional = commentDao.findById(commentId);
        // 判断是否有值返回
        if(optional.isPresent()){
            // 有值，有查询到数据，才可以使用get方法获取数据
            return optional.get();
        }
        return null;
    }

    /**
     * 修改
     * @param comment
     */
    public void update(Comment comment) {
        // 如果前端传递过来的数据不完整，将会导致更新后的这个文档丢失缺失的属性
        // mongodb里的update(条件，更新后的值)，这种是覆盖式更新
        // 解决：
        // 1. 使用updater更新器$set, mongoTemplate 使用的是mongo命令
        // Query query, 条件
        Query query = new Query();
        // {"_id",comment.get_id()}
        // 构建BasicDbObject
        query.addCriteria(Criteria.where("_id").is(comment.get_id()));
        // Update update 更新后的值， 使用更新器4set
        Update update = Update.update("content", comment.getContent());
        // String collectionName 集合的名称
        mongoTemplate.updateFirst(query,update,"comment");

        // 2. 先查询，把前端传过来不为null的属性更新到查询出来的对象里，再保存查询出来的对象
        //Comment comment1 = commentDao.findById(comment.get_id()).get();
        //comment1.setContent(comment.getContent());
        //commentDao.save(comment1);
    }

    /**
     * 删除
     * @param commentId
     */
    public void deleteById(String commentId) {
        commentDao.deleteById(commentId);
    }

    /**
     * 根据文章id查询评论
     * @param articleId
     * @return
     */
    public List<Comment> findByArticleId(String articleId) {
        List<Comment> comments = commentDao.findByArticleid(articleId);
        return comments;
    }

    /**
     * 点赞
     * @param commentId
     * @param loginUserId 这个参数是为了测试用的，真实开发下是用户的id是可以通过token获取的
     */
    public void thumbup(String commentId, String loginUserId) {
        // 防止重复点赞, redis中的key需要区分业务
        String key = "Comment_Thumbup_" + commentId;
        Long add = redisTemplate.opsForHyperLogLog().add(key, loginUserId);
        if(add == 0){
            // 返回值1代表是没有点赞过的，0 重复点赞
            throw new TensquareException("不能重复点赞");
        }

        // 方案一：
        //Comment comment1 = commentDao.findById(commentId).get();
        //comment1.setThumbup(comment1.getThumbup() + 1);
        //commentDao.save(comment1);
        // 方案二：db.comment.update({条件},{$inc:{key,count}}
        // 更新的条件，where 条件
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(commentId));
        // 更新器，增长
        Update update = new Update();
        // 点赞数量要增长1
        update.inc("thumbup", 1);

        mongoTemplate.updateFirst(query, update,"comment");
    }
}
